﻿using System.Collections.Generic;
using Helpers;
using QFramework;

namespace Gp.Scripts.Core {
    public enum InputLayer {
        /// <summary>
        ///  正常行动游玩
        /// </summary>
        Play = 1,

        /// <summary>
        /// 正在操作UI
        /// </summary>
        UI = 1 << 2,

        /// <summary>
        /// 检查模式
        /// </summary>
        Detail = 1 << 3,
    }

    public class RestrictMovementCommand {
        public bool IsRestrict;

        public RestrictMovementCommand(bool isRestrict) {
            IsRestrict = isRestrict;
        }
    }
    [AutoLoad()]
    public class InputLayerSystem : BaseGameSystem {
        private readonly Stack<InputLayer> _last = new();
        public InputLayer Layer => _stateMachine.CurrentStateId;
        private FSM<InputLayer> _stateMachine;
        
        private readonly List<object> _layerLockKeys = new();
        private bool CanSwitchBaseLayer => _layerLockKeys.Count == 0;


        /// <summary>
        /// 是否限制player行动 
        /// </summary>
        public bool BannedMovement { get; set; } = false;

        protected override void OnInit() {
            _stateMachine = new FSM<InputLayer>();
            _stateMachine.AddState(InputLayer.Play, new PlayState(_stateMachine, this));
            _stateMachine.AddState(InputLayer.UI, new UIState(_stateMachine, this));
            _stateMachine.AddState(InputLayer.Detail, new DetailState(_stateMachine, this));

            _stateMachine.StartState(InputLayer.Play);
        }

        


        public void SwitchToUILayer(object switchKey) {
            _layerLockKeys.Add(switchKey);
            _stateMachine.ChangeState(InputLayer.UI);
        }
        

        public void SwitchToBase(object switchKey) {
            for (int i = _layerLockKeys.Count - 1; i >= 0; i--) {
                var obj = _layerLockKeys[i];
                if (obj == null) _layerLockKeys.RemoveAt(i);
                else if (obj == switchKey) _layerLockKeys.RemoveAt(i);
            }
            
            if (CanSwitchBaseLayer) _stateMachine.ChangeState(InputLayer.Play);
        }


        public bool IsLayer(int layer) {
            return (layer & (int) Layer) == layer;
        }



        public class PlayState : AbstractState<InputLayer, InputLayerSystem> {
            public PlayState(FSM<InputLayer> fsm, InputLayerSystem target) : base(fsm, target) { }

            protected override void OnEnter() {
                // 处理禁止行动命令
                // Instance.RegisterEvent<RestrictMovementCommand>(HandleEvent);

                var player = ObjectHelper.PlayerCharacter;
                if (player == null) return;
                player.characterLocomotion.SetIsControllable(true);
                Global.Get<CursorManager>().SetMode(MouseMode.UI);
            }

            // protected override void OnExit() { 
            //     Instance.UnRegisterEvent<RestrictMovementCommand>(HandleEvent);
            // }
            //
            // private void HandleEvent(RestrictMovementCommand obj) {
            //     var player = ObjectHelper.PlayerCharacter;
            //     Instance.BannedMovement = obj.IsRestrict;
            //     player.characterLocomotion.SetIsControllable(!Instance.BannedMovement);
            // }
        }


        public class UIState : AbstractState<InputLayer, InputLayerSystem> {
            public UIState(FSM<InputLayer> fsm, InputLayerSystem target) : base(fsm, target) { }

            protected override void OnEnter() {
                var player = ObjectHelper.PlayerCharacter;
                player.characterLocomotion.SetIsControllable(false);
                // CursorManageSystem.Instance.SetMode(MouseMode.UI);

                // 更改摄像机鼠标跟随
                // if (HookCamera.Instance.Get<CameraController>().currentCameraMotor.cameraMotorType is
                //     CameraMotorTypeAdventure camera) {
                //     camera.allowOrbitInput = false;
                // }

                // 如果监听到退出事件则退出
                // Instance.RegisterEvent<ExitArgs>(Change);
            }

            protected override void OnExit() {
                // Instance.UnRegisterEvent<ExitArgs>(Change);
                // 更改摄像机鼠标跟随
                // if (HookCamera.Instance.Get<CameraController>().currentCameraMotor.cameraMotorType is
                //     CameraMotorTypeAdventure camera) {
                //     camera.allowOrbitInput = true;
                // }
            }

            // private void Change(ExitArgs obj) {
            //     // 退出至上一层
            //     mFSM.ChangeState(mFSM.PreviousStateId);
            // }
        }

        public class DetailState : AbstractState<InputLayer, InputLayerSystem> {
            public DetailState(FSM<InputLayer> fsm, InputLayerSystem target) : base(fsm, target) { }

            protected override void OnEnter() {
                var player = ObjectHelper.PlayerCharacter;
                player.characterLocomotion.SetIsControllable(false);
                Global.Get<CursorManager>().SetMode(MouseMode.UI);

                // 如果监听到退出事件则退出
                // Instance.RegisterEvent<ExitArgs>(Change);
            }
            //
            // protected override void OnExit() {
            //     // Instance.UnRegisterEvent<ExitArgs>(Change);
            // }
            //
            //
            // private static void Change(ExitArgs obj) {
            //     MainArchitecture.Interface.SendCommand(new ExitDetailModeCommand());
            // }
        }
    }


    public class ExitArgs { }
}